package com.globallogic.training.vaskulg.binarytree;

public class Node<T extends Comparable<T>> {
	private T value;
	private Node<T> parent;
	private Node<T> leftChild;
	private Node<T> rightChild;
	
	private static final String ROOT_NODE_STRING = "Root Node - %s\n";
	private static final String NODE_STRING = "Node %s\n";
	private static final String LEFT_BRANCH_OF_NODE = "%sLeft Branch of %s - %s\n";
	private static final String RIGHT_BRANCH_OF_NODE = "%sRight Branch of %s - %s\n";
	
	public Node(T value) {
		this.value  = value;
	}
		
	public T getValue() {
		return value;
	}

	public Node<T> getParent() {
		return parent;
	}

	public void setParent(Node<T> parent) {
		this.parent = parent;
	}

	public Node<T> getLeftChild() {
		return leftChild;
	}

	public void setLeftChild(Node<T> leftChild) {
		this.leftChild = leftChild;
		this.leftChild.setParent(this);
	}

	public Node<T> getRightChild() {
		return rightChild;
	}

	public void setRightChild(Node<T> rightChild) {
		this.rightChild = rightChild;
		this.rightChild.setParent(this);
	}

	private int getRightHegiht() {
		return (rightChild != null) ? rightChild.getHeight() + 1 : 1;
	}
	
	private int getLeftHegiht() {
		return (leftChild != null) ? leftChild.getHeight() + 1 : 1;
	}
	
	public int getHeight() {
		int leftHeight = getLeftHegiht();
		int rightHeight = getRightHegiht();

		return (leftHeight > rightHeight) ? leftHeight : rightHeight;
	}
	
	public void addValue(T value) {
		if (this.value.compareTo(value) < 0) {
			if (leftChild == null) {
				setLeftChild(new Node<T>(value));
			} else {
				leftChild.addValue(value);
			}
		} else if (this.value.compareTo(value) > 0) {
			if (rightChild == null) {
				setRightChild(new Node<T>(value));
			} else {
				rightChild.addValue(value);
			}
		}
	}

	@Override
	public String toString() {	
		String result;
		
		if (parent == null) {
			result =  String.format(ROOT_NODE_STRING, value.toString());
		} else {
			result =  String.format(NODE_STRING, value.toString());
		}
		
		if (leftChild != null) {
			result =  String.format(LEFT_BRANCH_OF_NODE, result, value.toString(), leftChild.toString());
		}
		
		if (rightChild != null) {
			result =  String.format(RIGHT_BRANCH_OF_NODE, result, value.toString(), rightChild.toString());
		}
		
		return result;
	}	
}
